home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / AHDI / TTFHDX / AHDI.S < prev    next >
Encoding:
Text File  |  2001-02-09  |  10.0 KB  |  502 lines

  1. * ahdi.s
  2.  
  3. *------------------------------------------------------------------------
  4. *                                    :
  5. *    ST SASI/AHDI hard disk driver                    :
  6. *    Copyright 1985 Atari Corp.                    :
  7. *                                    :
  8. *----                                    :
  9. * 31-Jan-1989 ml    Cut this out from the real AHDI.        :
  10. *            Only low-level routines are kept.        :
  11. *                                    :
  12. *------------------------------------------------------------------------
  13.  
  14. *----- System:
  15. flock        equ    $43e        ; FIFO lock variable
  16. _hz_200        equ    $4ba        ; system 200hz timer
  17.  
  18.  
  19. *----- Hardware:
  20. wdc        equ    $ffff8604
  21. wdl        equ    $ffff8606
  22. wdcwdl        equ    wdc        ; used for long writes
  23. xwdl        equ    wdl-wdc        ; offset from wdc to wdl
  24.  
  25. dmahi        equ    $ffff8609
  26. dmamid        equ    dmahi+2
  27. dmalow        equ    dmamid+2
  28. gpip        equ    $fffffa01
  29.  
  30.  
  31. *----- Tunable:
  32. ltimeout    equ    450000        ; long-timeout (3 S)
  33. stimeout    equ    15000        ; short-timeout (100 mS)
  34.  
  35.  
  36. *----- Declarations:
  37. tocount:    dc.l    1        ; count down
  38.  
  39.  
  40. *+
  41. * LONG _qdone() - Wait for command byte handshake
  42. * LONG _fdone() - Wait for operation complete
  43. * Passed:    nothing
  44. *
  45. * Returns:    EQ: no timeout
  46. *        MI: timeout condition
  47. *
  48. * Uses:        D0
  49. *
  50. * each pass through the loop takes 6.75 uS
  51. *-
  52. _fdone:    move.l    #ltimeout,tocount
  53.     bra    qd1
  54.  
  55. _qdone:    move.l    #stimeout,tocount
  56. qd1:    subq.l    #1,tocount        ; drop timeout count
  57.     bmi    qdq            ; (i give up, return NE)
  58.     btst    #5,gpip            ; interrupt?
  59.     bne    qd1            ; (not yet)
  60.  
  61.     moveq    #0,d0            ; return EQ (no timeout)
  62.     rts
  63.  
  64. qdq:    moveq    #-1,d0
  65.     rts
  66.  
  67.  
  68. *+
  69. * WORD _endcmd()
  70. * Wait for end of SASI command
  71. * Passed:    d0 value to be written to wdl
  72. *
  73. * Returns:    EQ: success (error code in D0.W)
  74. *        MI: timeout
  75. *        NE: failure (SASI error code in D0.W)
  76. *
  77. * Uses:        d0,d1
  78. *-
  79. _endcmd: move    d0,d1            ; preserve wdl value
  80.  
  81.     bsr    _fdone            ; wait for operation complete
  82.     bmi    endce            ; (timed-out, so complain)
  83.  
  84.     move.w    d1,wdl
  85.     nop
  86.     move.w    wdc,d0            ; get the result
  87.     and.w    #$00ff,d0        ; (clean it up), if non-zero should
  88.  
  89. endce:    rts                ;  do a ReadSense command to learn more
  90.  
  91.  
  92.  
  93. *-
  94. * _hread(sectno, count, buf, dev)
  95. * LONG sectno;         4(sp)
  96. * WORD count;         8(sp)
  97. * LONG buf;        $a(sp)    $b=high, $c=mid, $d=low
  98. * WORD dev;        $e(sp)
  99. *
  100. * Returns:    -1 on timeout
  101. *        0 on success
  102. *        nonzero on error
  103. *
  104. *-
  105.     .globl    _hread
  106. _hread:
  107.     movea.l    #wdc,a0            ; pointer to DMA chip
  108.     st    flock            ; lock FIFO
  109.  
  110.     move    #$88,xwdl(a0)
  111.     clr.l    d0
  112.     move.w    $0e(sp),d0        ; get unit number
  113.     lsl.w    #5,d0
  114.     swap    d0
  115.     ori.l    #$0008008a,d0        ; 08 wdc, 8a wdl
  116.     move.l    d0,(a0) ; wdcwdl
  117.  
  118.     move.l    $a(sp),-(sp)        ; set DMA address
  119.     bsr    _setdma
  120.     addq    #4,sp
  121.  
  122.     bsr    _setss            ; set sector and size
  123.     bmi    _hto
  124.  
  125.     move.w    #$190,xwdl(a0)
  126.     nop
  127.     move.w    #$90,xwdl(a0)
  128.     nop
  129.     move.w    8(sp),(a0) ;wdc        ; write sector count to DMA chip
  130.     nop
  131.     move.w    #$8a,xwdl(a0)
  132.     nop
  133.     move.l    #$00000000,(a0) ; wdcwdl; control byte  0 wdc 0 wdl
  134.  
  135.     move.w    #$8a,d0
  136.     bsr    _endcmd
  137. hrx:    bra    _hdone            ; cleanup after IRQ
  138.  
  139.  
  140. *-
  141. * _hwrite(sectno, count, buf, dev)
  142. * LONG sectno;         4(sp)
  143. * WORD count;         8(sp)
  144. * LONG buf;        $a(sp)    $b=high, $c=mid, $d=low
  145. * WORD dev;        $e(sp)
  146. *
  147. *-
  148.     .globl    _hwrite
  149. _hwrite:
  150.     movea.l    #wdc,a0            ; pointer to DMA chip
  151.     st    flock            ; lock FIFO
  152.  
  153.     move.l    $a(sp),-(sp)        ; set DMA address
  154.     bsr    _setdma
  155.     addq    #4,sp
  156.  
  157.     move.w    #$88,xwdl(a0)
  158.     clr.l    d0
  159.     move.w    $0e(sp),d0        ; get unit number
  160.     lsl.w    #5,d0
  161.     swap    d0
  162.     ori.l    #$000a008a,d0        ; 0a wdc 8a wdl
  163.     move.l    d0,(a0) ; wdcwdl
  164.  
  165.     bsr    _setss
  166.     bmi    _hto
  167.  
  168.     move.w    #$90,xwdl(a0)
  169.     nop
  170.     move.w    #$190,xwdl(a0)
  171.     nop
  172.     move.w    8(sp),(a0) ;wdc        ; sector count for DMA chip's benefit
  173.     nop
  174.     move.w    #$18a,xwdl(a0)
  175.     nop
  176.     move.l    #$00000100,(a0) ; wdcwdl
  177.  
  178.     move.w    #$18a,d0
  179.     bsr    _endcmd
  180.  
  181. hwx:    bra    _hdone            ; cleanup after IRQ
  182.  
  183.  
  184. *+
  185. * void _setdma(addr)
  186. * LONG addr;
  187. *-
  188. _setdma:
  189.     move.b    7(sp),dmalow
  190.     move.b    6(sp),dmamid
  191.     move.b    5(sp),dmahi
  192.     rts
  193.  
  194. *+
  195. * WORD _setss  -- set sector number and number of sectors
  196. *-
  197. _setss:    move.w    #$8a,xwdl(a0)
  198.  
  199.     bsr    _qdone            ; wait for controller to take command
  200.     bmi    setsse
  201.  
  202.     move.b    9(sp),d0        ; construct sector#
  203.     swap    d0
  204.     move.w    #$008a,d0
  205.     move.l    d0,(a0) ; wdcwdl    ; write MSB sector# + devno
  206.     bsr    _qdone
  207.     bmi    setsse
  208.  
  209.     move.b    10(sp),d0        ; write MidSB sector#
  210.     swap    d0
  211.     move.w    #$008a,d0
  212.     move.l    d0,(a0) ; wdcwdl
  213.     bsr    _qdone
  214.     bmi    setsse
  215.  
  216.     move.b    11(sp),d0        ; write LSB sector#
  217.     swap    d0
  218.     move.w    #$008a,d0
  219.     move.l    d0,(a0) ; wdcwdl
  220.     bsr    _qdone
  221.     bmi    setsse
  222.  
  223.     move.w    12(sp),d0        ; write sector count
  224.     swap    d0
  225.     move.w    #$008a,d0
  226.     move.l    d0,(a0) ; wdcwdl
  227.     bsr    _qdone
  228.  
  229. setsse:    rts
  230.  
  231. _hto:    moveq    #-1,d0        ; indicate timeout
  232. _hdone:    move.w    #$80,wdl    ; Landon's code seems to presume we
  233.     nop            ;  put this back to $80
  234.     tst.w    wdc
  235.     clr    flock        ; NOW, signal that we are done
  236.     rts
  237.  
  238.  
  239. * page 
  240. *+
  241. *  _doformat - format hard disk
  242. *
  243. *    Synopsis:    LONG _doformat(dev, interlv)
  244. *        WORD dev;            4(sp).W
  245. *        WORD interlv;            6(sp).W
  246. *
  247. *-
  248. acfmt:    dc.b    4    ; format command + devno (upper 3 bits)
  249.     dc.b    0    ; (unused)
  250.     dc.b    0    ; (unused) data pattern
  251. ac_in:    dc.b    0,0    ; interleave factor MSB, LSB
  252.     dc.b    0    ; reserved
  253.     .even
  254.  
  255.     .globl    _doformat
  256. _doformat:
  257.     move.w    4(sp),d0        ; set dev#
  258.     lsl.b    #5,d0            ; up 5 bits, fill in 0s
  259.     or.b    #4,d0            ; OR-in with FORMAT command
  260.     move.b    d0,acfmt        ; stuff into command frame
  261.     move.b    6(sp),ac_in        ; set interleave
  262.     move.b    7(sp),ac_in+1
  263.  
  264.     lea    acfmt(pc),a0        ; pick up pointer to the command block
  265.     clr.w    d0
  266.     st    flock            ; lock FIFO
  267.     move.w    #$88,wdl
  268.     move.b    (a0)+,d0        ; get the command byte
  269.     swap    d0
  270.     move.w    #$8a,d0
  271.     move.l    d0,wdc            ; byte wdc 8a wdl
  272.  
  273.     moveq    #(5-1),d1        ; write remaining 5 bytes of command
  274. fmt1:    bsr    _qdone
  275.     bmi    _hto
  276.     move.b    (a0)+,d0        ; next byte of command
  277.     swap    d0
  278.     move.w    #$8a,d0
  279.     move.l    d0,wdcwdl
  280.     dbra    d1,fmt1
  281.  
  282. fmt2:    btst    #5,gpip            ; wait (forever) for completion
  283.     bne    fmt2
  284.     move.w    wdc,d0            ; get the status
  285.     andi.w    #$00FF,d0        ; only low byte is significant
  286.     bra    _hdone            ; cleanup after IRQ
  287.  
  288.  
  289. *+
  290. *  _mode_set - set hard disk format parameters
  291. *
  292. *    Synopsis:    LONG _mode_set(dev, len, parms)
  293. *        WORD dev;            4(sp).W
  294. *        WORD len;            6(sp).W
  295. *        char *parms;            8(sp).L
  296. *
  297. *-
  298.     .globl    _mode_set
  299. _mode_set:
  300.     st    flock            ; lock FIFO
  301.     move.l    8(sp),-(sp)        ; -> parameter block address
  302.     bsr    _setdma            ; set DMA there
  303.     addq    #4,sp
  304.  
  305. * write command and dev#
  306.     move.w    #$88,wdl
  307.     move.w    4(sp),d0        ; d0 = (dev << 5) << 16
  308.     lsl.b    #5,d0
  309.     swap    d0            ; in upper word
  310.     or.l    #$0015008a,d0        ; write dev# + ModeSelect + FIFO bits
  311.     move.l    d0,wdcwdl        ; mdsel+dev wdc 8a wdl (byte 0)
  312.     bsr    _qdone
  313.     bmi    wdx
  314.  
  315.     move.l    #$0000008a,wdcwdl    ; byte 1
  316.     bsr    _qdone
  317.     bmi    wdx
  318.  
  319.     move.l    #$0000008a,wdcwdl    ; byte 2
  320.     bsr    _qdone
  321.     bmi    wdx
  322.  
  323.     move.l    #$0000008a,wdcwdl    ; byte 3
  324.     bsr    _qdone
  325.     bmi    wdx
  326.  
  327.     move.w    6(sp),d0        ; # bytes of parameter
  328.     swap    d0            ; in upper word
  329.     or.l    #$0000008a,d0
  330.     move.l    d0,wdcwdl        ; byte 4
  331.     bsr    _qdone
  332.     bmi    wdx
  333.  
  334.     move.w    #$90,wdl        ; reset the DMA chip
  335.     nop
  336.     move.w    #$190,wdl
  337.     nop
  338.     move.w    #$01,wdc        ; 1 sector of DMA (actually less)
  339.     nop
  340.     move.w    #$18a,wdl
  341.     nop
  342.     move.l    #$00000100,wdcwdl    ; byte 5 (control byte)
  343.     move.w    #$18a,d0        ; wdl value
  344.     bsr    _endcmd            ; wait for command completion
  345. wdx:    bra    _hdone
  346.  
  347.  
  348. * page 
  349. *+
  350. *  _md_sense - get hard disk format parameters
  351. *
  352. *    Synopsis:    LONG _md_sense(dev, parms)
  353. *        WORD dev;            4(sp).W
  354. *        char *parms;            6(sp).L
  355. *
  356. *-
  357.     .globl    _md_sense
  358. _md_sense:
  359.     st    flock            ; lock FIFO
  360.     move.l    6(sp),-(sp)        ; -> parameter block address
  361.     bsr    _setdma            ; set DMA there
  362.     addq    #4,sp
  363.  
  364. * write command and dev#
  365.     move.w    #$88,wdl
  366.     move.w    4(sp),d0        ; d0 = (dev << 5) << 16
  367.     lsl.b    #5,d0
  368.     swap    d0            ; in upper word
  369.     or.l    #$001a008a,d0        ; write dev# + ModeSense + FIFO bits
  370.     move.l    d0,wdcwdl        ; mdsense+dev wdc 8a wdl (byte 0)
  371.     bsr    _qdone
  372.     bmi    wdx1
  373.  
  374.     move.l    #$0000008a,wdcwdl    ; byte 1
  375.     bsr    _qdone
  376.     bmi    wdx1
  377.  
  378.     move.l    #$0000008a,wdcwdl    ; byte 2
  379.     bsr    _qdone
  380.     bmi    wdx1
  381.  
  382.     move.l    #$0000008a,wdcwdl    ; byte 3
  383.     bsr    _qdone
  384.     bmi    wdx1
  385.  
  386.     move.l    #$0016008a,wdcwdl    ; 22 bytes of parameters (byte 4)
  387.     bsr    _qdone
  388.     bmi    wdx1
  389.  
  390.     move.w    #$190,wdl        ; reset the DMA chip
  391.     nop
  392.     move.w    #$90,wdl
  393.     nop
  394.     move.w    #$01,wdc        ; 1 sector of DMA (actually less)
  395.     nop
  396.     move.w    #$8a,wdl
  397.     nop
  398.     move.l    #0,wdcwdl        ; byte 5 (control byte)
  399.     move.w    #$8a,d0            ; wdl value
  400.     bsr    _endcmd            ; wait for command completion
  401. wdx1:    bra    _hdone
  402.  
  403.  
  404. * page 
  405. *+
  406. *  _rq_sense - get sense data from target
  407. *
  408. *    Synopsis:    LONG _rq_sense(dev, data)
  409. *        WORD dev;            4(sp).W
  410. *        char data[];            6(sp).L
  411. *
  412. *-
  413.     .globl    _rq_sense
  414. _rq_sense:
  415.     st    flock            ; lock FIFO
  416.     move.l    6(sp),-(sp)        ; -> sense data buffer address
  417.     bsr    _setdma            ; set DMA there
  418.     addq    #4,sp
  419.  
  420.      move.w    #$190,wdl        ; reset the DMA chip
  421.     nop
  422.     move.w    #$90,wdl
  423.     nop
  424.     move.w    #$01,wdc        ; 1 sector of DMA (actually less)
  425.     nop
  426.  
  427. * write command and dev#
  428. * have to do this 4 times to have controller write it into RAM
  429.     move    #3,d2            ; (count = 4)
  430. loop4x:
  431.     move.w    #$88,wdl
  432.     move.w    4(sp),d0        ; d0 = (dev << 5) << 16
  433.     lsl.b    #5,d0
  434.     swap    d0            ; in upper word
  435.     or.l    #$0003008a,d0        ; write dev#+Request Sense+FIFO bits
  436.     move.l    d0,wdcwdl        ; rqsense+dev wdc 8a wdl (byte 0)
  437.     bsr    _qdone
  438.     bmi    wdq1
  439.  
  440.     move.l    #$0000008a,wdcwdl    ; byte 1
  441.     bsr    _qdone
  442.     bmi    wdq1
  443.  
  444.     move.l    #$0000008a,wdcwdl    ; byte 2
  445.     bsr    _qdone
  446.     bmi    wdq1
  447.  
  448.     move.l    #$0000008a,wdcwdl    ; byte 3
  449.     bsr    _qdone
  450.     bmi    wdq1
  451.  
  452.     move.l    #$0000008a,wdcwdl    ; byte 4
  453.     bsr    _qdone
  454.     bmi    wdq1
  455.  
  456.     move.w    #$8a,wdl
  457.     nop
  458.     move.l    #0,wdcwdl        ; byte 5 (control byte)
  459.     move.w    #$8a,d0            ; wdl value
  460.     bsr    _endcmd            ; wait for command completion
  461.     bmi    wdq1
  462.     
  463.     move.l    _hz_200,d1
  464.     addq.l    #2,d1
  465. wait:
  466.     cmp.l    _hz_200,d1        ; delay 2 ticks between
  467.     bcc    wait            ; driver calls
  468.     dbra    d2,loop4x        ; go back until done 4 times
  469.  
  470. wdq1:    bra    _hdone
  471.  
  472.  
  473. * page 
  474. *+
  475. *  _tstunt - test unit ready
  476. *
  477. *    Synopsis:    LONG _tstunt(dev)
  478. *        WORD dev;            4(sp).W
  479. *
  480. *-
  481.     .globl    _tstunt
  482. _tstunt:
  483.     move.w    4(sp),d0        ; set dev#
  484.     lsl.b    #5,d0            ; up 5 bits, fill in 0s
  485.  
  486.     st    flock            ; lock FIFO
  487.     move.w    #$88,wdl
  488.     swap    d0
  489.     move.w    #$8a,d0
  490.     move.l    d0,wdc            ; byte wdc 8a wdl
  491.  
  492.     moveq    #(5-1),d1        ; write remaining 5 bytes of command
  493. tu1:    bsr    _qdone
  494.     bmi    _hto
  495.     move.l    #$0000008a,wdcwdl    ; next byte of command
  496.     dbra    d1,tu1
  497.  
  498.     move.w    #$8a,d0
  499.     bsr    _endcmd
  500.     bra    _hdone            ; cleanup after IRQ
  501.  
  502.